﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FR.SAFTAnalyser.Model.EF
{
    internal class EntitiesMaper
    {
        internal static void MapHeader(Model.Header h, SaftModelContext context)
        {
            Header header = new Header();

            header.AuditFileVersion = h.AuditFileVersion;
            header.BusinessName = h.BusinessName;
            if (h.CompanyAddress != null)
            {
                header.AddressDetail = h.CompanyAddress.AddressDetail;
                header.BuildingNumber = h.CompanyAddress.BuildingNumber;
                header.City = h.CompanyAddress.City;
                header.Country = h.CompanyAddress.Country;
                header.PostalCode = h.CompanyAddress.PostalCode;
                header.Region = h.CompanyAddress.Region;
                header.StreetName = h.CompanyAddress.StreetName;
            }
            header.CompanyID = h.CompanyID;
            header.CompanyName = h.CompanyName;
            if (h.CurrencyCode != null)
                header.CurrencyCode = h.CurrencyCode.ToString();
            header.DateCreated = h.DateCreated;
            header.Email = h.Email;
            header.EndDate = h.EndDate;
            header.Fax = h.Fax;
            header.FiscalYear = h.FiscalYear;
            header.HeaderComment = h.HeaderComment;
            header.ProductCompanyTaxID = h.ProductCompanyTaxID;
            header.ProductID = h.ProductID;
            header.ProductVersion = h.ProductVersion;
            header.SoftwareCertificateNumber = h.SoftwareCertificateNumber;
            header.StartDate = h.StartDate;
            header.TaxAccountingBasis = h.TaxAccountingBasis.ToString();
            header.TaxEntity = h.TaxEntity;
            header.TaxRegistrationNumber = h.TaxRegistrationNumber;
            header.Telephone = h.Telephone;
            header.Website = h.Website;

            context.Header.Add(header);
            context.SaveChanges();
        }

        internal static void MapProducts(Model.Product[] p, SaftModelContext context)
        {
            foreach (var item in p)
            {
                Product produto = new Product();
                produto.ProductCode = item.ProductCode;
                produto.ProductDescription = item.ProductDescription;
                produto.ProductGroup = item.ProductGroup;
                produto.ProductNumberCode = item.ProductNumberCode;
                produto.ProductType = item.ProductType.ToString();

                context.Products.Add(produto);
            }

            context.SaveChanges();
        }

        internal static void MapCustomers(Model.Customer[] c, SaftModelContext context)
        {
            foreach (var item in c)
            {
                Customer customer = new Customer();
                customer.AccountID = item.AccountID;
                if (item.BillingAddress != null)
                {
                    customer.BillingAddress = new AddressStructure();
                    customer.BillingAddress.AddressDetail = item.BillingAddress.AddressDetail;
                    customer.BillingAddress.BuildingNumber = item.BillingAddress.BuildingNumber;
                    customer.BillingAddress.City = item.BillingAddress.City;
                    customer.BillingAddress.Country = item.BillingAddress.Country;
                    customer.BillingAddress.PostalCode = item.BillingAddress.PostalCode;
                    customer.BillingAddress.Region = item.BillingAddress.Region;
                    customer.BillingAddress.StreetName = item.BillingAddress.StreetName;
                }
                customer.CompanyName = item.CompanyName;
                customer.Contact = item.Contact;
                customer.CustomerID = item.CustomerID;
                customer.CustomerTaxID = item.CustomerTaxID;
                customer.Email = item.Email;
                customer.Fax = item.Fax;
                customer.SelfBillingIndicator = item.SelfBillingIndicator;
                if (item.ShipToAddress != null && item.ShipToAddress.Length > 0)
                {
                    customer.ShipToAddress = new AddressStructure();
                    customer.ShipToAddress.AddressDetail = item.ShipToAddress[0].AddressDetail;
                    customer.ShipToAddress.BuildingNumber = item.ShipToAddress[0].BuildingNumber;
                    customer.ShipToAddress.City = item.ShipToAddress[0].City;
                    customer.ShipToAddress.Country = item.ShipToAddress[0].Country;
                    customer.ShipToAddress.PostalCode = item.ShipToAddress[0].PostalCode;
                    customer.ShipToAddress.Region = item.ShipToAddress[0].Region;
                    customer.ShipToAddress.StreetName = item.ShipToAddress[0].StreetName;
                }
                customer.Telephone = item.Telephone;
                customer.Website = item.Website;

                context.Customers.Add(customer);
            }

            context.SaveChanges();
        }

        internal static void MapSuppliers(Model.Supplier[] s, SaftModelContext context)
        {
            foreach (var item in s)
            {
                Supplier supplier = new Supplier();
                supplier.AccountID = item.AccountID;
                supplier.CompanyName = item.CompanyName;
                supplier.Contact = item.Contact; 
                supplier.Email = item.Email;
                supplier.Fax = item.Fax;
                supplier.SelfBillingIndicator = item.SelfBillingIndicator;
                supplier.SupplierID = item.SupplierID;
                supplier.SupplierTaxID = item.SupplierTaxID;
                supplier.Telephone = item.Telephone;
                supplier.Website = item.Website;
                if (item.BillingAddress != null)
                {
                    supplier.BillingAddress = new SupplierAddressStructure();
                    supplier.BillingAddress.AddressDetail = item.BillingAddress.AddressDetail;
                    supplier.BillingAddress.BuildingNumber = item.BillingAddress.BuildingNumber;
                    supplier.BillingAddress.City = item.BillingAddress.City;
                    supplier.BillingAddress.Country = item.BillingAddress.Country;
                    supplier.BillingAddress.PostalCode = item.BillingAddress.PostalCode;
                    supplier.BillingAddress.Region = item.BillingAddress.Region;
                    supplier.BillingAddress.StreetName = item.BillingAddress.StreetName;
                }
                if (item.ShipFromAddress != null)
                {
                    supplier.ShipFromAddress = new SupplierAddressStructure();
                    supplier.ShipFromAddress.AddressDetail = item.ShipFromAddress[0].AddressDetail;
                    supplier.ShipFromAddress.BuildingNumber = item.ShipFromAddress[0].BuildingNumber;
                    supplier.ShipFromAddress.City = item.ShipFromAddress[0].City;
                    supplier.ShipFromAddress.Country = item.ShipFromAddress[0].Country;
                    supplier.ShipFromAddress.PostalCode = item.ShipFromAddress[0].PostalCode;
                    supplier.ShipFromAddress.Region = item.ShipFromAddress[0].Region;
                    supplier.ShipFromAddress.StreetName = item.ShipFromAddress[0].StreetName;
                }

                context.Suppliers.Add(supplier);
            }

            context.SaveChanges();
        }

        internal static void MapSalesInvoices(Model.SourceDocumentsSalesInvoices i, SaftModelContext context, bool joinMode)
        {
            if (joinMode)
            {
                //ler os valores dos somatorios
                SourceDocumentsSalesInvoices t =
                    (from si in context.SalesInvoices
                     select si).FirstOrDefault();
                if (t != null)
                {
                    //somar os valores por defeito
                    t.NumberOfEntries = (int.Parse(t.NumberOfEntries) + int.Parse(i.NumberOfEntries)).ToString();
                    t.TotalCredit += i.TotalCredit;
                    t.TotalDebit += i.TotalDebit;
                }
            }
            else
            {
                SourceDocumentsSalesInvoices invoices = new SourceDocumentsSalesInvoices();

                invoices.NumberOfEntries = i.NumberOfEntries;
                invoices.TotalCredit = i.TotalCredit;
                invoices.TotalDebit = i.TotalDebit;

                context.SalesInvoices.Add(invoices);
            }

            context.SaveChanges();
        }

        internal static void MapInvoices(Model.SourceDocumentsSalesInvoicesInvoice[] i, SaftModelContext context)
        {
            foreach (var fileInvoices in i)
            {
                SourceDocumentsSalesInvoicesInvoice newInvoice = new SourceDocumentsSalesInvoicesInvoice();
                newInvoice.CustomerID = fileInvoices.CustomerID;
                if (fileInvoices.DocumentTotals != null)
                {
                    newInvoice.GrossTotal = fileInvoices.DocumentTotals.GrossTotal;
                    newInvoice.NetTotal = fileInvoices.DocumentTotals.NetTotal;
                    newInvoice.TaxPayable = fileInvoices.DocumentTotals.TaxPayable;
                }
                newInvoice.Hash = fileInvoices.Hash;
                newInvoice.HashControl = fileInvoices.HashControl;
                newInvoice.InvoiceDate = fileInvoices.InvoiceDate;
                newInvoice.InvoiceNo = fileInvoices.InvoiceNo;
                newInvoice.Period = fileInvoices.Period;
                newInvoice.SelfBillingIndicator = fileInvoices.SpecialRegimes != null ? fileInvoices.SpecialRegimes.SelfBillingIndicator : "--";
                newInvoice.SystemEntryDate = fileInvoices.SystemEntryDate;
                newInvoice.TransactionID = fileInvoices.TransactionID;
                newInvoice.InvoiceStatus = fileInvoices.DocumentStatus.InvoiceStatus.ToString();
                newInvoice.InvoiceType = fileInvoices.InvoiceType.ToString();

                #region Lines
                foreach (var fileLine in fileInvoices.Line)
                {
                    SourceDocumentsSalesInvoicesInvoiceLine newLine = new SourceDocumentsSalesInvoicesInvoiceLine();
                    newLine.Invoice = newInvoice;

                    newLine.CreditAmount = fileLine.ItemElementName == ItemChoiceType5.CreditAmount ? fileLine.Item : 0;
                    newLine.DebitAmount = fileLine.ItemElementName == ItemChoiceType5.DebitAmount ? fileLine.Item : 0;
                    newLine.Description = fileLine.Description;
                    newLine.LineNumber = fileLine.LineNumber;
                    newLine.ProductCode = fileLine.ProductCode;
                    newLine.ProductDescription = fileLine.ProductDescription;
                    newLine.Quantity = fileLine.Quantity;
                    newLine.SettlementAmount = fileLine.SettlementAmount;
                    if (fileLine.Tax != null)
                    {
                        newLine.Tax = new Tax();
                        newLine.Tax.TaxCode = fileLine.Tax.TaxCode;
                        newLine.Tax.TaxCountryRegion = fileLine.Tax.TaxCountryRegion;
                        newLine.Tax.TaxAmount = fileLine.Tax.ItemElementName == ItemChoiceType1.TaxAmount ? fileLine.Tax.Item : 0;
                        newLine.Tax.TaxPercentage = fileLine.Tax.ItemElementName == ItemChoiceType1.TaxPercentage ? fileLine.Tax.Item : 0;
                        newLine.Tax.TaxType = fileLine.Tax.TaxType.ToString();
                    }
                    newLine.TaxExemptionReason = fileLine.TaxExemptionReason;
                    newLine.TaxPointDate = fileLine.TaxPointDate;
                    newLine.UnitOfMeasure = fileLine.UnitOfMeasure;
                    newLine.UnitPrice = fileLine.UnitPrice;

                    context.InvoiceLines.Add(newLine);
                }
                #endregion Lines

                context.Invoices.Add(newInvoice);
                context.SaveChanges();
            }
        }
    }
}
